package com.geovis.emergency.spd.controller.pc;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.geovis.common.auth.util.AuthUtil;
import com.geovis.common.core.api.Result;
import com.geovis.common.core.controller.BaseController;
import com.geovis.common.file.dto.FileDTO;
import com.geovis.common.file.handler.IFileHandler;
import com.geovis.emergency.spd.biz.pc.service.IPcDrillDisasterEventService;
import com.geovis.emergency.spd.biz.pc.service.IPcDrillDisasterService;
import com.geovis.emergency.spd.biz.pc.service.IPcDrillService;
import com.geovis.emergency.spd.biz.pc.service.IPcPlanDutyDeptService;
import com.geovis.emergency.spd.biz.pc.service.impl.PcDrillServiceImpl;
import com.geovis.emergency.spd.biz.system.service.ISystemDeptService;
import com.geovis.emergency.spd.biz.system.service.ISystemDeptUserService;
import com.geovis.emergency.spd.biz.system.service.ISystemFileService;
import com.geovis.emergency.spd.entity.command.enums.PlanFileTypeEnum;
import com.geovis.emergency.spd.entity.command.pojo.vo.CommandDrillDisasterVo;
import com.geovis.emergency.spd.entity.command.pojo.vo.CommandDrillEventAndPlanVo;
import com.geovis.emergency.spd.entity.command.pojo.vo.CommandDrillOrgVo;
import com.geovis.emergency.spd.entity.pc.entity.PcDisaster;
import com.geovis.emergency.spd.entity.pc.entity.PcDrill;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillDisaster;
import com.geovis.emergency.spd.entity.pc.entity.PcDrillDisasterEvent;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcMessageConstant;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillDisasterEventQueryDTO;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillDisasterSchedulingDTO;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillDisasterSubmitDTO;
import com.geovis.emergency.spd.entity.pc.pojo.enums.DisasterEventStatusEnum;
import com.geovis.emergency.spd.entity.pc.pojo.vo.*;
import com.geovis.emergency.spd.entity.system.entity.SystemDeptUser;
import com.geovis.emergency.spd.entity.system.entity.SystemFile;
import com.geovis.emergency.spd.entity.system.pojo.vo.SystemUserVo;
import com.geovis.emergency.spd.util.MsgUtil;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 应急预案指挥模块-演练灾害表 前端控制器
 * </p>
 *
 * @author Lonsho
 * @since 2022-06-08
 */
@RestController
@RequestMapping("/pc/drill/disaster")
@RequiredArgsConstructor
@Api(value = "应急预案指挥模块-演练配置方案", tags = "应急预案指挥模块-配置方案接口")
@Slf4j
@Validated
public class PcDrillDisasterController  extends BaseController<IPcDrillDisasterService> {

    private final IPcDrillDisasterEventService pcDrillDisasterEventService;
    private final IPcPlanDutyDeptService pcPlanDutyDeptService;

    private final ISystemDeptUserService systemDeptUserService;
    private final ISystemDeptService systemDeptService;

    private final IPcDrillService pcDrillService;

    @ApiOperation(value = "获取演练组织架构(指挥系统调用)", notes = "获取演练组织架构")
    @GetMapping("/command/getDrillOrgs")
    public Result<List<CommandDrillOrgVo>> getDrillOrgs(String drillId) {
        return Result.ok(baseService.getSchedulingDrillOrgs(drillId));
    }

    @ApiOperation(value = "获取演练的事件列表(指挥系统调用)", notes = "获取演练的事件列表(指挥系统调用)")
    @GetMapping("/command/getDisasterList")
    public Result<List<CommandDrillDisasterVo>> getDisasterList(String drillId) {
        return Result.ok(baseService.getDisasterList(drillId));
    }

    @ApiOperation(value = "获取演练的事件消息详情与方案(指挥系统调用)", notes = "获取演练的事件消息详情与方案(指挥系统调用)")
    @GetMapping("/command/getEventAndPlan")
    public Result<List<CommandDrillEventAndPlanVo>> getEventAndPlan(String drillId,String drillDisasterId) {
        return Result.ok(baseService.getEventAndPlan(drillId,drillDisasterId));
    }

    @ApiOperation(value = "获取预案的文件列表(指挥系统调用)", notes = "获取预案的文件列表(指挥系统调用)")
    @GetMapping("/command/getPlanFile")
    public Result<List<SystemFile>> getPlanFile(String pcDrillId,PlanFileTypeEnum type) {
        return Result.ok(baseService.getPlanFile(pcDrillId,type));
    }


    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "保存事件", notes ="保存事件")
    @PostMapping({"/submitEvent"})
    public Result<Boolean> submitEvent(@Validated @RequestBody PcDrillDisasterSubmitDTO submitDTO){
        baseService.submitEvent(submitDTO);
        PcDrill pcDrill=pcDrillService.getById(submitDTO.getPcDrillId());
        String content= "演练【"+pcDrill.getName()+"】已创建";
        MsgUtil.sendDrillMsg(submitDTO.getPcDrillId(), AuthUtil.getCurrentUserId(), PcMessageConstant.TYPE_DRILL_ADD,"创建演练",content,submitDTO.getPcDrillId());
        return Result.ok();
    }
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "保存应急指挥事件", notes ="保存应急指挥事件")
    @PostMapping({"/submitEvent2"})
    public Result schedulingSubmitEvent(@Validated @RequestBody PcDrillDisasterSchedulingDTO submitDTO){
        baseService.schedulingSubmitEvent(submitDTO);
        return Result.ok();
    }
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "清空事件", notes ="清空事件")
    @PostMapping({"/removeEvent/{pcDrillId}"})
    public Result cleanEvent(@PathVariable("pcDrillId") String pcDrillId){
        baseService.cleanEvent(pcDrillId);
        return Result.ok();
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "获取事件详情", notes ="获取事件详情")
    @PostMapping({"/detailEvent/{pcDrillId}"})
    public Result<PcDrillDisasterVO> detailEvent(@PathVariable("pcDrillId") String pcDrillId){
        return Result.ok(baseService.detailEvent(pcDrillId));
    }

    @ApiOperation(value = "查询人员", notes ="查询人员")
    @GetMapping({"/queryUsers"})
    public Result<PcDrillOrgUsersVO> queryUsers(String pcDrillId, String orgId, String keyword){
        return Result.ok(baseService.queryUsers(pcDrillId,orgId,keyword));
    }

    @ApiOperation(value = "新版获取组织架构及人员2-获取人员", notes ="新版获取组织架构及人员2")
    @GetMapping({"/queryOrgUsers"})
    public Result<List<SystemUserVo>> queryOrgUsers(String deptId){
        return Result.ok(baseService.queryOrgUsers(deptId));
    }

    @ApiOperation(value = "新版获取组织架构及人员2-获取部门", notes ="新版获取组织架构及人员2")
    @GetMapping({"/queryOrgs"})
    public Result<List<SystemDeptVo>> queryOrgs(String deptId){
        return Result.ok(baseService.queryOrgs(deptId));
    }


    @ApiOperation(value = "新版获取组织架构及人员2-搜索人员", notes ="新版获取组织架构及人员2")
    @GetMapping({"/searchUsers"})
    public Result<PcDrillOrgUsersVO> searchUsers(String keyword){
        return Result.ok(baseService.searchUsers(keyword));
    }

    @ApiOperation(value = "新版获取某个组织选中的所有人", notes ="新版获取某个组织架构选中的所有人")
    @GetMapping({"/queryOrgSelectUsers"})
    public Result<List<SystemUserVo>> queryOrgSelectUsers(String pcDrillId,String orgId){
        return Result.ok(baseService.queryOrgSelectUsers(pcDrillId,orgId));
    }

    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "获取灾害事件或者演练灾害事件", notes ="获取灾害事件详情")
    @PostMapping({"/getDetail"})
    public Result<PcDrillDisasterEventVO> getEventDetail(@RequestBody PcDrillDisasterEventQueryDTO pcDrillDisasterEventQueryDTO){
        return Result.ok(baseService.getDetail(pcDrillDisasterEventQueryDTO));
    }


    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "获取预设事件", notes ="获取预设事件")
    @PostMapping({"/presetEvent/{pcDrillId}"})
    public Result<List<PcDisaster>> presetEvent(@PathVariable("pcDrillId") String pcDrillId){
        return Result.ok(baseService.presetEvent(pcDrillId));
    }

    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "获取演练灾害事件", notes ="获取演练灾害事件")
    @PostMapping({"/disasterList/{pcDrillId}"})
    public Result<List<PcDrillDisaster>> disasterList(@PathVariable("pcDrillId") String pcDrillId,@RequestParam(value = "type",required = false) String type){
        return Result.ok(baseService.list(Wrappers.<PcDrillDisaster>lambdaQuery()
                .eq(PcDrillDisaster::getPcDrillId,pcDrillId)
                .in(StrUtil.isNotBlank(type), PcDrillDisaster::getSourceType,StrUtil.split(type,","))
                .orderByAsc(PcDrillDisaster::getEventType)
                .orderByDesc(PcDrillDisaster::getCreateTime)
        ));
    }
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "获取续报演练灾害事件", notes ="获取续报演练灾害事件")
    @PostMapping({"/continueList/{pcDrillId}"})
    public Result<List<PcDrillDisaster>> continueList(@PathVariable("pcDrillId") String pcDrillId){
        //事件续报，所有已经发生过的消息续报
        Set<String> drillDisasterIds = pcDrillDisasterEventService.list(
                Wrappers.lambdaQuery(PcDrillDisasterEvent.class)
                        .select(PcDrillDisasterEvent::getPcDrillDisasterId)
                        .isNotNull(PcDrillDisasterEvent::getPcDrillDisasterId)
                        .eq(PcDrillDisasterEvent::getPcDrillId, pcDrillId)
                        .in(PcDrillDisasterEvent::getStatus, Lists.newArrayList(
                                DisasterEventStatusEnum.IN_PROGRESS.getCode(),
                                DisasterEventStatusEnum.COMPLETED.getCode()
                        ))
        ).stream().map(PcDrillDisasterEvent::getPcDrillDisasterId).collect(Collectors.toSet());
        if (CollUtil.isNotEmpty(drillDisasterIds)){
            List<PcDrillDisaster> list = baseService.list(
                    Wrappers.lambdaQuery(PcDrillDisaster.class).in(PcDrillDisaster::getId, drillDisasterIds)
            );
            return Result.ok(list);
        }
        return Result.ok(Lists.newArrayList());
    }
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "获取演练预案组织架构", notes ="获取演练预案组织架构")
    @PostMapping({"/drillPlanDuty/{pcPlanId}"})
    public Result<PcDrillDisasterOrgVO> drillPlanDuty(@PathVariable("pcPlanId") String planId){
        return Result.ok(baseService.getPlanDuty(planId, true));
    }
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "基础部门用户接口", notes ="基础部门用户接口")
    @PostMapping({"/basicDeptUser"})
    public Result<PcDrillDisasterOrgVO> basicDeptUser(){
        PcDrillDisasterOrgVO pcDrillDisasterOrgVO = new PcDrillDisasterOrgVO();
        List<PcDrillDutyOrgUserVO> pcPlanDutyDeptList = pcPlanDutyDeptService.selectPlanDuty(null).stream().map(s -> BeanUtil.toBean(s, PcDrillDutyOrgUserVO.class)).collect(Collectors.toList());
        pcDrillDisasterOrgVO.setDutyDutyOrgUserList(systemDeptService.deptTree());

        Set<String> deptIdList = pcPlanDutyDeptList.stream().map(PcDrillDutyOrgUserVO::getDeptId).collect(Collectors.toSet());
        List<SystemDeptUser> list = Lists.newArrayList();
        if (CollUtil.isNotEmpty(deptIdList)){
            list = systemDeptUserService.list(
                    Wrappers.lambdaQuery(SystemDeptUser.class).in(SystemDeptUser::getDeptId, deptIdList)
            );
        }
        pcDrillDisasterOrgVO.setDeptUserList(
                list.stream().map(s -> {
                    DeptUserVO deptUserVO = new DeptUserVO();
                    deptUserVO.setId(s.getUserId());
                    deptUserVO.setDeptId(s.getDeptId());
                    deptUserVO.setName(s.getUserName());
                    deptUserVO.setDeptName(s.getDeptName());
                    return deptUserVO;
                }).collect(Collectors.toList())
        );
        return Result.ok(pcDrillDisasterOrgVO);
    }
}
